package mop.model;

import mop.exception.IllegalIdException;
import mop.util.event.PropertyChangeListener;

/**
 * Abstract Model Class
 * in the name of Pull Up refactoring
 * 
 * @author MOP Team 7
 * 
 * @invar 	Identifier is valid
 * 			|isValidIdentifier(getId())
 */

public abstract class AbstractModel implements ModelInterface
{

	/**
	 * Default Constructor
	 * 
	 * @param id	Identifier for this model
	 * 
	 * @post identifier is set when valid
	 * 	|getId() == id
	 * @post set propertyChangeSupport
	 * 
	 * @throws IllegalIdException
	 * 	|!isValidId(id)
	 */
	protected AbstractModel(String id) throws IllegalIdException
	{
		if(!isValidId(id))
			throw new IllegalIdException(id);
		this.id = id;
		this.propertyChangeSupport = new PropertyChangeSupport(this);
	}

	/***************************************************************************
	 * 						Model interface
	 ***************************************************************************/
	
	/**
	 * get a reference to the interface
	 */
	public abstract ModelInterface getInterface();
	
	/***************************************************************************
	 * 							Identifier
	 ***************************************************************************/
	
	
	/**
	 * @see ModelInterface#getId()
	 */
	public String getId() 
	{
		return id;
	}
	
	 /**
	  * Checks if the passed identifier is valid
	  * @param id	The identifier to check
	  * @return true if the passed id is not empty and its not null
	  *  |((!(id().equals("")) && id != null))
	  */
	 public static boolean isValidId(String id)
	 {
		 return (id != null && !(id.trim().equals("")));
	 }
	 
	
	 /**
	  * variable for the id of the project
	  */
	private final String id;
	
	/***************************************************************************
	 * 						Object interface
	 ***************************************************************************/
	
	/**
	 * to String function -- used for comparison reasons
	 * 
	 * @return description
	 */
	public String toString()
	{
		return this.getId();
	}
	
	/**
	 * Check whether given object is same as this object
	 * Yes, we use instanceof (NOOOOOOOOOOOOOOO!), but otherwise madame Lizkov would complain.
	 * 
	 * @return true if two objects have the same description and id
	 */
	public boolean equals(Object obj)
	{
		if(!(obj instanceof ModelInterface))
			throw new IllegalArgumentException("Given object must implement modelinterface");
		
		return (this.toString().equals(obj.toString())) && (this.getId().equals(((ModelInterface) obj).getId())) ;
		
	}
	
	/***************************************************************************
	 * 						Property change support
	 ***************************************************************************/
	
	/**
	 * @see 	ModelInterface#addPropertyChangeListener(PropertyChangeListener)
	 * @effect 	Listener added
	 * 			| propertyChangeSupport.addPropertyChangeListener(listener)
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener)
	{
		propertyChangeSupport.addPropertyChangeListener(listener);
	}

	/**
	 * @see 	ModelInterface#removePropertyChangeListener(PropertyChangeListener)
	 * @effect 	Listener removed
	 * 			| propertyChangeSupport.removePropertyChangeListener(listener)
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener)
	{
		propertyChangeSupport.removePropertyChangeListener(listener);
	}
	
	/**
	 * Property change support instance
	 */
	protected final PropertyChangeSupport propertyChangeSupport;

}
